﻿using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Naruto.CQRS.Command;
using Naruto.CQRS.Query;

namespace Naruto.CQRS;

/// <summary>
/// 服务注册
/// </summary>
public static class ServiceDi
{
    /// <summary>
    /// 注册服务
    /// </summary>
    /// <param name="service"></param>
    /// <param name="types"></param>
    public static IServiceCollection AddNarutoCqrs(this IServiceCollection service, params Type[] types)
    {
        service.TryAddScoped<ICommandDispatcher,CommandDispatcher>();
        service.TryAddScoped<IQueryDispatcher,QueryDispatcher>();
        service.RegisterEvent(types);
        return service;
    }

    /// <summary>
    /// 注册事件
    /// </summary>
    /// <param name="service"></param>
    /// <param name="types"></param>
    private static void RegisterEvent(this IServiceCollection service, params Type[] types)
    {
        foreach (var type in types)
        {
            //查找命令接口
            foreach (var itemCommandType in type.Assembly.GetTypes().Where(a =>
                         a.GetInterface(nameof(ICommand)) != null && !a.IsInterface && !a.IsAbstract))
            {
                //获取接口类型
                var interfaceType = itemCommandType.GetInterface(typeof(ICommand<>).Name);
                if (interfaceType != null) service.TryAddScoped(interfaceType, itemCommandType);
            }

            //查找查询接口
            foreach (var itemQueryType in type.Assembly.GetTypes().Where(a =>
                         a.GetInterface(nameof(IQuery)) != null && !a.IsInterface && !a.IsAbstract))
            {
                //获取接口类型
                var interfaceType = itemQueryType.GetInterface(typeof(IQuery<,>).Name);
                if (interfaceType != null) service.TryAddScoped(interfaceType, itemQueryType);
            }
        }
    }
}